<template>
    <el-dialog class="component_dialog"
               :class="{'app_dialog': isApp, 'above_dialog': abowDialog, 'center_dialog': center,
                   'no_footer': dialogOption.hideBtn, 'footer_center': dialogOption.footerCenter,
                   'hide_footer': hideFooter,
                   'hide_header': !dialogOption.showClose && !this.$utils.isNotEmpty(dialogOption.title)}"
               :title="dialogOption.title" :show-close="dialogOption.showClose"
               :visible.sync="dialogOption.visible"
               :width="dialogOption.width" :append-to-body="dialogOption.appendToBody"
               :before-close="dialogOption.handleClose" v-dialogDrag="abowDialog || center">
        <div class="dialog_content" v-if="dialogOption.visible"
             :style="contentStyle">
            <components :is="component" :propsData="propsData" :ref="dialogOption.ref"
                        v-if="component" @event="handleComponentEvent"
                        v-get-ref="getRefFn" />
        </div>
        <div slot="footer" class="dialog-footer" v-if="!hideFooter">
            <template v-for="(item, index) in dialogBtns">
                <el-button @click="item.method(dialogOption, $refs)"
                           :key="index" :type="item.type"
                           :size="item.size" :class="item.className"
                           v-btn-loading="typeof item.loading === 'undefined' ? false : item.loading">
                    {{ item.text }}
                </el-button>
            </template>
        </div>
    </el-dialog>
</template>

<script>
export default {
    name: 'ComponentDialog',
    inject: {
        setChildrenRef: {
            default: () => {
            },
        },
        getParentRef: {
            from: 'getRef',
            default: () => {
            },
        },
        getParentChildrenRef: {
            from: 'getChildrenRef',
            default: () => {
            },
        },
    },
    props: {
        options: {
            type: Object,
            default() {
                return {
                    btns: undefined,
                };
            }
        },
        isApp: {
            type: Boolean,
            default: false,
        },
        abowDialog: {
            type: Boolean,
            default: false,
        },
        center: {
            type: Boolean,
            default: false,
        },
        height: {
            type: Number,
            default: 0,
        },
    },
    data() {
        const _this = this;
        return {
            defaultDialogOpt: {
                visible: false,
                ref: 'component',
                width: '430px',
                handleClose(done) {
                    _this.$emit('closeEvent', _this.$refs.component);
                    done();
                },
                hideBtn: false,
                footerCenter: false,
                dialogCenter: false,
                noCloseBtn: false,
                showClose: true,
            },
            dialogOption: {},
            component: undefined,
            propsData: undefined,
            closeBtn: {
                text: '关闭',
                method(option) {
                    option.visible = false;
                },
            },
            dialogBtns: [],
        };
    },
    computed: {
        contentStyle() {
            let style = {};
            if (this.height > 0) {
                let subHeight = 140;
                if (!this.dialogOption.showClose && !this.$utils.isNotEmpty(this.dialogOption.title)) {
                    subHeight = 77;
                }
                let height = this.height - subHeight;
                style.height = `${ height }px`;
            } else {
                style.height = 'auto';
            }
            return style;
        },
        hideFooter() {
            return this.dialogOption.hideBtn || !this.$utils.isNotEmptyList(this.dialogBtns);
        },
    },
    watch: {
        options: {
            handler() {
                this.initData(this.options);
            },
            deep: true,
            immediate: true,
        },
    },
    methods: {
        getRefFn(c) {
            let ref = this.dialogOption.ref || 'component';
            typeof this.setChildrenRef === 'function' && this.setChildrenRef(ref, c);
        },
        openDialog(options) {
            this.initData(options);
        },
        closeDialog() {
            this.handleComponentEvent('closeDialog');
        },
        initData(options) {
            this.dialogOption = $.extend({}, this.defaultDialogOpt, options);
            this.component = options.component;
            let btns = [];
            if (!this.dialogOption.noCloseBtn) {
                btns.push(this.closeBtn);
            }
            if (options.btns) {
                btns = btns.concat(options.btns);
            }
            this.dialogBtns = btns;
            if (options.propsData) {
                this.propsData = $.extend({}, options.propsData);
            }
            if (this.propsData !== undefined && Object.keys(this.propsData).length === 0) {
                this.propsData = undefined;
            }
        },
        initCloseBtn() {
            if (!this.dialogOption.hideBtn) {
                this.dialogBtns = [ this.closeBtn ];
            }
        },
        handleComponentEvent(data) {
            let _this = this;
            _this.$nextTick(() => {
                if ('closeDialog' === data) {
                    _this.dialogOption = $.extend({}, _this.dialogOption, {
                        visible: false,
                    });
                    _this.$emit('closeEvent', _this.$refs.component);
                } else if ('initCloseBtn' === data) {
                    _this.initCloseBtn();
                } else {
                    data._component = _this.$refs.component;
                    _this.$emit('event', data);
                }
            });
        },
    },
}
</script>

<style lang="less" rel="stylesheet/less" scoped>
.component_dialog {
    /deep/ .el-dialog__body {
        .dialog_content {
            height: 100%;
            overflow: auto;
        }
    }

    /deep/ .el-dialog__footer {
        padding-top: 0;

        .el-button {

            &.el-button + {
                margin-left: 10px;
            }
        }
    }
}

.app_dialog {
    /deep/ .el-dialog__body {
        background-color: #f7f8fa;

        .dialog_content {
            background-color: #fff;
            width: 400px;
            height: 100%;
            overflow: hidden;
            border-radius: 12px;
            margin: 0 auto;
            box-shadow: #ebedf0 0 4px 12px;
        }
    }
}

.no_footer {
    /deep/ .el-dialog__body {
        height: calc(100% - 54px) !important;
    }
}

.footer_center {
    /deep/ .el-dialog__footer {
        text-align: center;
    }
}

.center_dialog {
    /deep/ .el-dialog {
        margin-top: 0 !important;
        position: absolute;
        left: 50% !important;
        top: 50% !important;
        transform: translateX(-50%) translateY(-50%);
    }
}

.hide_header {
    /deep/ .el-dialog__header {
        display: none;
    }

    /deep/ .el-dialog__body {
        height: calc(100% - 47px) !important;
    }
}
</style>
